第三步:玩玩串口发送
先上图,后面紧接着是代码,代码呢,主要是运编译器里贩看到的头文件里的类,类里面每个函都说明了参数及其作用,所以用起来比较方便,头文件后是我用的对应的代码,看起来这个板子玩基本功能是不是很简单呢……
日语没过二级(我就不翻译了,将就看还是大概能懂的)代码从下一行开始:
/*******************************************************************************
* GR-SAKURA LIBRARY LICENSE. LIMITATION and DISCLAIMER of WARRANTY
*
* This software is supplied by Tokushu Denshi Kairo Inc. and is only intended
* for use with Gadget Renesas projects. No other uses are authorized.
* This software is owned by Tokuden and is protected under all applicable laws,
* including copyright laws. Disclosure or redistribution to others this headder
* file and related library file alone is not allowed.
* You can redistribute the executable object file (only SREC or BIN file) which
* is generated as a result of compilation and link your program.
* Of cource the limitation of this library license does not effect to your code.
* THIS SOFTWARE IS PROVIDED "AS IS" AND TOKUDEN MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* Tokuden reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* http://rx.tokudenkairo.co.jp/
* (C) Copyright 2011-2012 Tokushu Denshi Kairo Inc.
*******************************************************************************/
#ifndef __H_RXDUINO_SERIAL
#define __H_RXDUINO_SERIAL
/**************************************************************************//**
* @file serial.h
* @brief UARTやUSB仮想COMポートを使うためのライブラリ
******************************************************************************/
#include <stdlib.h>
#include "rxduino.h"
//#include "Print.h"
#include "../tkdnhal/tkdn_sci.h"
#ifdef __cplusplus
extern "C" {
#endif
extern SCI_PORT SCI_DEFAULT_PORT;
//------------------------------------------------------------------
// シリアルポート
//------------------------------------------------------------------
/*! @class CSerial
@brief シリアル通信を制御するクラス。このクラスのインスタンスは、何らかのシリアルポートを制御する。
@details レガシーなUARTや、USB仮想COMポートを統一の取れた手段で扱うことができる。
@note システム起動時に既に、Serial、Serial1、Serial2、Serial3という4つのグローバルな<BR>
インスタンスが宣言されている。これらのインスタンスはデフォルトでは物理的にどこかのポートに<BR>
関連付けられているわけではない。Serail?.beginを行って、はじめて実際のポートに関連づけられる。<BR>
*/
class CSerial {
//class CSerial: public Print {
private:
SCI_PORT port; /* ポート番号。 SCI_SCI0P2x SCI_SCI1JTAG SCI_SCI2A SCI_SCI2B SCI_SCI6A SCI_SCI6B SCI_USB0の中から指定 */
sci_str sci;
size_t print_number(unsigned long val,int base);
public:
CSerial(SCI_PORT port=SCI_NONE); //
~CSerial();
//! シリアル通信ポートの初期化 デフォルトのポート(SCI_USB0)が使用される
/*!
@param bps ボーレート
@note ボーレートには任意の値を設定してよいが、9600,38400,115200などが無難である
@return なし
@include serial1.cpp
*/
void begin(int bps);
//! ポートを指定して、シリアル通信ポートの初期化
/*!
@param bps ボーレート
@param port
- SCI_NONE : SCIポートを使用しない
- SCI_AUTO : SCIを自動選択
- SCI_USB0 : USB0 の仮想COMポートを使う
- SCI_USB1 : USB1 の仮想COMポートを使う (未実装)
- SCI_SCI0P2x : SCI0 (ポートP20,P21と兼用) を使う
- SCI_SCI1JTAG : SCI1 (ポートPF0,PF2,JTAGと兼用) を使う
- SCI_SCI2A : SCI2A (ポートP13,P12)を使う
- SCI_SCI2B : SCI2B (ポートP50,P52)を使う
- SCI_SCI6A : SCI6A (ポートP00,P01)を使う ※SAKURAでは使えない
- SCI_SCI6B : SCI6B (ポートP32,P33)を使う
@warning SCI_AUTOを指定した場合、SCI0,SCI1,USB0から最初に何かを受信するまで制御を返しません。
@return なし
@note 通常のシリアルポートオープンの例
@include serial2.cpp
@note 複数のシリアルポートをオープンする例
@include serial3.cpp
*/
void begin(int bps,SCI_PORT port);
//! シリアル通信ポートのクローズ
/*!
@param なし
@return なし
*/
void end();
/*!
@brief このシリアルをデフォルトのシリアルとして設定し、printf等の出力先にする
@details printf()など、標準出力がSerialから出力されるようになります。
@note printf()は\\nが来るまで内部でバッファしてしまうので、改行のない文字列を即座に出力するには、
setvbuf()も必要です。
@param なし
@return なし
@include serial_setdefault.cpp
*/
void setDefault();
//! シリアルポートから何バイトのデータが読み取れるかを返す
/*!
@param なし
@return シリアルバッファにあるデータのバイト数。0の場合はデータなし
*/
int available();
//! シリアルポートの受信バッファから1バイトのデータを読み出します
/*!
@param なし
@return 先頭のデータ。データなしの場合は-1が返る
*/
int read();
//! シリアルポートの受信バッファにある先頭のデータを読みます。バッファ中の読み込み位置は変更しないので、バッファを覗くだけです。CRLFの変換は行われません。
/*!
@param なし
@return 先頭のデータ。データなしの場合は-1が返る
*/
int peek();
//! シリアルポートの送信バッファが空になるまで待ちます。受信バッファをどうするかは、Arduinoの仕様が変わっているので、検討中です。
/*!
@param なし
@return なし
*/
void flush();
//! この関数は実装していない
// void serialEvent();
//! シリアルポートに1文字出力する
/*!
@param val 文字コード
@return 実際に出力した文字数
*/
size_t write(unsigned char val);
//! シリアルポートに文字列を出力する
/*!
@param str ヌル(\\0)で終わる文字列
@return 実際に出力した文字数
*/
size_t write(const char *str);
//! シリアルポートに指定した長さのデータ列を出力する
/*!
@param buf 出力データ
@param len 出力データの長さ
@return 実際に出力したバイト数
*/
size_t write(const unsigned char *buf,int len);
//! シリアルポートに文字列を出力する
/*!
@param str ヌル(\\0)で終わる文字列
@return 実際に出力したバイト数
*/
size_t print(const char str[]);
//! シリアルポートに文字を出力する
/*!
@param c 出力したい文字コード
@return 実際に出力したバイト数
*/
size_t print(char c);
//! シリアルポートに値(数字)を出力する
/*!
@param c 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t print(unsigned char c, int print_type=DEC);
//! シリアルポートに値(数字)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t print(int val, int print_type=DEC);
//! シリアルポートに値(数字)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t print(unsigned int val, int print_type=DEC);
//! シリアルポートに値(数字)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t print(long val, int print_type=DEC);
//! シリアルポートに値(数字)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t print(unsigned long val, int print_type=DEC);
//! シリアルポートに浮動小数点数を出力する
/*!
@param val 出力したい値
@param fpdigit 桁数
@return 実際に出力したバイト数
*/
size_t print(double val, int fpdigit=2);
//! シリアルポートに文字列を出力して改行コード(\\n\\r)を出力する
/*!
@param str ヌル(\\0)で終わる文字列
@return 実際に出力した文字数
*/
size_t println(const char str[]);
//! シリアルポートに文字を出力して改行コード(\\n\\r)を出力する
/*!
@param c 出力したい文字コード
@return 実際に出力したバイト数
*/
size_t println(char c);
//! シリアルポートに値(数字)を出力して改行コード(\\n\\r)を出力する
/*!
@param c 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t println(unsigned char c, int print_type=DEC);
//! シリアルポートに値(数字)を出力して改行コード(\\n\\r)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t println(int val, int print_type=DEC);
//! シリアルポートに値(数字)を出力して改行コード(\\n\\r)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t println(unsigned int val, int print_type=DEC);
//! シリアルポートに値(数字)を出力して改行コード(\\n\\r)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t println(long val, int print_type=DEC);
//! シリアルポートに値(数字)を出力して改行コード(\\n\\r)を出力する
/*!
@param val 出力したい値
@param print_type 基数
- 2: 二進数
- 8: 8進数
- 10: 10進数 (デフォルト)
- 16: 16進数
@return 実際に出力したバイト数
*/
size_t println(unsigned long val, int print_type=DEC);
//! シリアルポートに浮動小数点数を出力して改行コード(\\n\\r)を出力する
/*!
@param val 出力したい値
@param fpdigit 桁数
@return 実際に出力したバイト数
*/
size_t println(double val, int fpdigit=2);
//! シリアルポートに改行コードのみ出力して改行コード(\\n\\r)を出力する
/*!
@param なし
@return 実際に出力したバイト数
*/
size_t println(void);
//! このクラスに結びつけられている特電HALのシリアル構造体へのハンドルを得る
/*!
@param なし
@details より低レベルなシリアル操作を行うときに使います
@return シリアルクラスのハンドル
*/
sci_str *get_handle();
};
extern CSerial Serial;
extern CSerial Serial1;
extern CSerial Serial2;
extern CSerial Serial3;
#ifdef __cplusplus
}
#endif
#endif // __H_RXDUINO_SERIAL
我自已的代码从下一行开始:
/*GR-SAKURA Sketch Template Version: V1.02*/
#include <rxduino.h>
#define INTERVAL 1000
void setup()
{
// 后面的参数大概就是说,使用P13和P12作为串口的TXD和RXD***日语会猜就行
Serial.begin(9600,SCI_SCI2A); // SCI_SCI2A : SCI2A (ポートP13,P12)を使う
}
void loop()
{
delay(INTERVAL);
Serial.println("----------------------");
Serial.println("EEPW-Sakura-SerialTest");
Serial.println("----------------------");
}
---------------------------------------------------------------------------the END of Step3
在使用串口输入功能时同样只需要配置樱花板的波特率及端口号,然后Serial.read()用来从串口获取数据。Arduino提供的这个函数是非阻塞的,也就是说不论串口上是否真的有数据到到,该函数都会立即返回,Serial.read()每次只读取一个数据.当串口上有数据到达的时候,该函数返回的值是获取到的数据对应的ASSIC码,当没有数据到达时,返回的是-1。
在Arduino语言中提供了一个函数来读取串口缓冲区中的字节数--Serial.available()。该函数可以帮助我们在应用中更灵活地使用串口功能。Arduino串口的缓冲区中最多可以缓冲128字节。
下面先看看简单测试的结果:
我表示已经一次性发了很多数据了,这个量足够我们平时用了,就测到这里为止吧…………
以下是我编写的程序代码:
/*GR-SAKURA Sketch Template Version: V1.02*/
#include <rxduino.h>
void setup()
{
Serial.begin(9600,SCI_SCI2A);
}
char Data_Ser = 0;
void loop()
{
while(Serial.available()>0)
{
Data_Ser= Serial.read();
if((Data_Ser)!=(-1))
{
Serial.print(Data_Ser);
}
}
}
-----------------------------------------------------------------------------End of Step4
第5步:IIC通讯实验
先来看看网上查到的关于Arduino提供的IIC函数的说明:
begin()//初始化wire库,配置IIC总线主机
begin(address)//带地址参数address的就是配置从机,不带的就是配置主机
requestFrom(address,count)//在启动IIC总线后,可以继续访问另一个地址的从设备,及次数
beginTransmission(address)//准备开始跟地址address从机通讯
endTransmission()//结束本次通讯,与上一个函数成对使用
send()//发送数据
byte available()//用于判断数据是否有效,有效才接收
byte receive()//接收数据
onReceive(handler)//从机接收主机发送来的数据
onRequest()//从机请求主机发送数据
下面是樱花板与之对应的函数:
void i2c_init(i2c_info *i2c,int sda, int scl);
void i2c_init_slave(i2c_info *i2c,int sda, int scl,unsigned char addr);
int i2c_request_from(i2c_info *i2c,unsigned char address, int count);
int i2c_available(i2c_info *i2c);
int i2c_read(i2c_info *i2c);
void i2c_begin_transmission(i2c_info *i2c,unsigned char address);
int i2c_write(i2c_info *i2c,unsigned char data);
unsigned char i2c_end_transmission(i2c_info *i2c);
具体的说明容测试成功后再写,先看看简单的测试平台,功能性测试
AT24C08A
简单的测试环境
IIC调试更新2012年12月16日
主机代码
#include <rxduino.h>
/*master*/
#include <Wire.h>
void setup()
{
Wire.begin(); //Start IIC bus,no address means master
Serial.begin(9600); // Start UART,9600bps
Serial.println("Ready");
}
int val = 0;
void loop()
{
while(val == 0)//第一次进入循环一定待待串口指定工作方式
{
if(Serial.available()>0)
{
val = Serial.read();
}
}
if(Serial.available()>0)//后面只是在需要更改工作方式时才用串口发送数据
{
val = Serial.read();
}
if(val == '1')
{
Serial.println("Cammand to Slave( Address is 4)...");
Wire.beginTransmission(4);
Wire.write(1);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(2);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(2);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
delay(700);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
delay(300);
Wire.write(1);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Serial.println("Cammand to Slave( Address is 5)...");
Wire.beginTransmission(5);
Wire.write(2);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
Wire.write(1);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(500);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
Wire.write(1);
delay(500);
Wire.endTransmission();
delay(1000);
}
else if(val == '2')
{
Serial.println("Cammand to Slave( Address is 5)...");
Wire.beginTransmission(5);
Wire.write(1);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
Wire.write(2);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(700);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(300);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(700);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(300);
Wire.write(2);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(700);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
delay(300);
Wire.write(1);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(5);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Serial.println("Cammand to Slave( Address is 4)...");
Wire.beginTransmission(4);
Wire.write(2);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(1);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
delay(500);
Wire.write(6);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(3);
Wire.endTransmission();
delay(1000);
Wire.beginTransmission(4);
Wire.write(1);
delay(500);
Wire.endTransmission();
delay(1000);
}
}
从机1(地址为4)代码
/*slaver1__COM10 SlaverAddress is 4*/
#include <Wire.h>
int LED = 13;
int LED1 = 12;
int LED2 = 10;
void setup()
{
Wire.begin(4); // with address 4 means slaver
Wire.onReceive(receiveEvent);//When Master's data is arrivel,call reveiveEvent Function
pinMode(LED,OUTPUT);// set LED pinMode as OUTPUT
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
digitalWrite(LED,HIGH);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
}
void loop()
{
;
}
void receiveEvent(int howMany)
{
int c = Wire.read();//get a byte
if(c == 1)
{
digitalWrite(LED,LOW);//light the leg
}
else if(c == 2)
{
digitalWrite(LED1,LOW);//off the led
}
else if(c == 3)
{
digitalWrite(LED2,LOW);
}
else
{
digitalWrite(LED,HIGH);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
}
}
从机2(地址为5)代码
/*slaver2__COM9 SlaverAddress is 5*/
#include <Wire.h>
int LED = 13;
int LED1 = 12;
int LED2 = 10;
void setup()
{
Wire.begin(5); // with address 4 means slaver
Wire.onReceive(receiveEvent);//When Master's data is arrivel,call reveiveEvent Function
pinMode(LED,OUTPUT);// set LED pinMode as OUTPUT
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
digitalWrite(LED,HIGH);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
}
void loop()
{
;
}
void receiveEvent(int howMany)
{
int c = Wire.read();//get a byte
if(c == 1)
{
digitalWrite(LED,LOW);//light the leg
}
else if(c == 2)
{
digitalWrite(LED1,LOW);//off the led
}
else if(c == 3)
{
digitalWrite(LED2,LOW);
}
else
{
digitalWrite(LED,HIGH);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
}
}
从机代码使用相关说明:
从机程序是在Arduino的IDE下编译,MEGA8中运行,与樱花板无关。使用的是MEGA自带的Arduino默认的IIC接口,且带外部上拉电阻2K。
实验视频分享:
串口实时显示与主机通信的从机及地址:
中间停了些天,终于结题了…………不过更深入的就看后期了……
先看效果图
原代码如下:
/*GR-SAKURA Sketch Template Version: V1.01*/
#include <rxduino.h>
#include "Ethernet.h"
TEthernet Client_ethernet;
EthernetClient Client_client;
#define INTERVAL 100
unsigned char Dev_mac[6]={0x22,0x10,0xc6,0xc6,0x00,0x02};
unsigned char Dev_ip[4]={192,168,26,12};
unsigned char Server_ip[4]={192,168,26,188};
short Server_port=7;
void setup()
{
pinMode(PIN_LED0,OUTPUT);
pinMode(PIN_LED1,OUTPUT);
pinMode(PIN_LED2,OUTPUT);
pinMode(PIN_LED3,OUTPUT);
Client_ethernet.begin(Dev_mac, Dev_ip);
Client_client.connect(Server_ip,Server_port);
}
unsigned char Client_Data[]="EEPW_Sakura_NetTest\r\n";
unsigned char Client_Data1[]="*******************\r\n";
void loop()
{
delay(INTERVAL);
delay(INTERVAL);
delay(INTERVAL);
delay(INTERVAL);
delay(INTERVAL);
delay(INTERVAL);
delay(INTERVAL);
Client_client.write(Client_Data,sizeof(Client_Data));
Client_client.write(Client_Data1,sizeof(Client_Data1));
}
说明(如何加入以太网相关的库,必须中向工程中导入含有"Ethernet.h"的库文件)
点击后会有提示出现,根据提示操作即可导入相关的库。
以太网头文件在工程里导入库后可以下载,下面对某些函数进行相关说明:
void begin(byte mac[6], byte ip[4], byte dns[4], byte gateway[4], byte subnet[4]);
该函数用于初始化设备(樱花板)的网络参数,函数最多可以有5个参数,最少1个参数,不过参数得按顺序来对应,比如只有一个参数的时候只配置MAC地址,而其它参数则自动配置。无特殊要求一般只配置前两个参数,若想要自动获取IP地址,则只配置前一个参数即可。
bool connect(byte server[4],unsigned short port);
该函数用于连接服务器,所需要的参数是服务器的地址和对应该应用的端口。
void write(unsigned char *buf,int len);
该函数用于向当前连接发送数据,两个参数分别是数据指针和数据长度。当然该函数还有其他形式,可以根据参数的不同按不同的方式完成功能:
void write(unsigned char c);
void write(const char *str);
待续……
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |